<?php
   namespace backend\service;

   use backend\component\BackendBaseService;
   use common\models\base\Attachment;
   use common\models\base\AttachmentService;
   use yii\image\drivers\Image;
   class UploadService extends BackendBaseService{
       private $oriName;

       public $validateOption = [
           'extensions' => 'jpg,jpeg,png,gif,zip,rar,pdf,doc,docx,ppt,pptx,xls,xlsx,txt,dwg,dxf,dwt',
           'maxSize' => 5242880,
       ];
       private $_imageExt = ['.jpg','.jpeg','.png','.gif'];
       private $output = ['error' => 0,'msg'=>'','data'=>''];

       private $imagePathFormat = "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}";
       private $filePathFormat = "upload/file/{yyyy}{mm}{dd}/{time}{rand:6}";

       public function actionMain($file){
            return $this->upBase64($file);
           //var_dump($html);
       }

       private function upBase64($file) {
           $this->oriName = mb_substr(substr($file['name'],0,strrpos($file['name'],'.')),0,127);
           $size =$file['size'];
           $ext = strtolower(strrchr($file['name'],'.'));
         //  var_dump($ext);
         //  die();
           if (!$ext) {
               $this->output['errno'] = 1;
               $this->output['msg'] = "非法文件类型";
               return $this->output;
           }
           $tmpExt = substr($ext,1);
           $tempFile = $file['tmp_name'];

           /* $error = [];
           $uploadFile = UploadedFile::getInstanceByName("Filedata");
           $validator = new FileValidator($this->validateOption);

           if (!$validator->validate($uploadFile,$errno)) {
                $this->output['errno'] = 1;
                $this->output['msg'] = $error;
                return $this->output;
            }*/
           //是否为图片
           $isImage = false;
           $pathFormat = $this->filePathFormat;//\Yii::$app->request->post("filePathFormat");
           if (in_array($ext,$this->_imageExt)) {
               $isImage = true;
               $pathFormat = $this->imagePathFormat;//\Yii::$app->request->post("imagePathFormat");
           }
           $fullPathName = $this->getFullName($pathFormat);
           $targetFilePathName = \Yii::$app->params["attach.image.path"] . DIRECTORY_SEPARATOR. $fullPathName.$ext;
           if (!$this->createDir($targetFilePathName)) {
               $this->output['errno'] = 1;
               $this->output['msg'] = "创建失败，是否有写入权限!";
               return $this->output;
           }
           $model = new Attachment();
           $model->original = $this->oriName;
           $model->path = $this->getPath($fullPathName);
           $model->name = $this->getName($targetFilePathName);
           $model->ext = $ext;
           $model->size = $size;

           if (!$model->save()) {
               unlink($tempFile);
               $this->output['errno'] = 1;
               $this->output['msg'] = "数据保存到数据库失败,原因：".$model->getErrorsToString();
               return $this->output;
           }
           if (!(move_uploaded_file($tempFile,$targetFilePathName) && file_exists($targetFilePathName))) {
               $this->output['errno'] = 1;
               $this->output['msg'] = "文件上传失败";
               //上传失败，删除数据库记录
               $model->delete();
               unlink($tempFile);
               return $this->output;
           }

           $as_id = 0;
           $service = \Yii::$app->request->post("service",0);
           $service_id = \Yii::$app->request->post("service_id",0);
           $isBindTable = \Yii::$app->request->post("isBindTable",0);
           if ($isBindTable) {
               $params['service'] = $service;
               $params['service_id'] = $service_id;
               $params['attach_id'] = $model->id;
               $multiImage = \Yii::$app->request->post("multiImage",false);
               if ($multiImage) {
                   $params['status'] = 1;
                   $params['sort'] = AttachmentService::intMaxSort($service,$service_id);
               }
               $aModel = new AttachmentService();
               if (!($aModel->load($params,"") && $aModel->save())) {
                   //上传失败，删除数据库记录

                   $model->delete();
                   unlink($targetFilePathName);
                   $this->output['errno'] = 1;
                   $this->output['msg'] = "绑定附件表失败";
                   return $this->output;
               }
               $as_id = $aModel->id;
       }
       //如果是图片&& 配置了服务类型则坚持是否要生成缩略图
           if ($isImage && $service && isset(AttachmentService::$thumbSize[$service])) {
               $thumbs = AttachmentService::$thumbSize[$service];
               foreach ($thumbs as $size => $method) {
                   list($width,$height) = explode("x",$size);
                   //生成缩略图
                   $this->buildThumb($targetFilePathName,$width,$height,$method);
               }
           }
           $imageServer = \Yii::$app->params["attach.image.url"];
           $this->output['msg'] = '上传成功';
           $this->output['data'] = [$imageServer.'/' .$model->path."/".$model->name.$model->ext];  //['server'=>$imageServer,'url'=> $model->path."/".$model->name.$model->ext,'as_id'=>$as_id];
           return $this->output;
       }

       /**
        * 生成缩络图
        * @param $targetFile
        * @param $width
        * @param $height
        * @param $method
        */
       public function buildThumb($targetFile,$width,$height,$method,$proportion = 0) {

           $image = \Yii::$app->image->load($targetFile);
           $imgInfo = getimagesize($targetFile);
           $img_w = $imgInfo[0];
           $img_h = $imgInfo[1];
           $dst_w = $width;
           $dst_h = $height;
           $x = $y = 0;
           if (($width > $img_w && $height > $img_h) || ($height > $img_h && $width == 0) || ($width > $img_w && $height == 0)){
               $proportion = 1;
           }
           if($width> $img_w)
           {
               $dst_w = $width = $img_w;
           }
           if($height> $img_h)
           {
               $dst_h = $height = $img_h;
           }

           if(!$width && !$height && !$proportion)
           {
               return false;
           }

           if (!$proportion) {
               //剪切
               if ($method == AttachmentService::IMAGE_CUT) {
                   if (!$dst_h){
                       $height = $dst_h = $dst_w;
                   }
                   if (!$dst_w){
                       $width = $dst_w = $dst_h;
                   }
                   $propor = min(max($dst_w/$img_w,$dst_h / $img_h),1);
                   $dst_w = (int)round($img_w * $propor);
                   $dst_h = (int)round($img_h * $propor);
                   $x = ($width - $dst_w) / 2;
                   $y = ($height - $dst_h) /2;
               } else {
                   //压缩
                   if ($dst_w xor $dst_h){
                       if ($dst_w && !$dst_h){
                           $propor = $dst_w / $img_w;
                           $height = $dst_h = $img_h * $propor;
                       }
                       elseif(!$dst_w && $dst_h){
                           $propor = $dst_h / $img_h;
                           $width = $dst_w = $img_w * $propor;
                       }
                   }
               }
           } else {
               $proportion = min($proportion,1);
               $height = $dst_h = $img_h * $proportion;
               $width  = $dst_w = $img_w * $proportion;
           }
           if ($method == AttachmentService::IMAGE_CUT) {
               $image->crop($width,$height,$x,$y)->background("#fff");
           } else {
               $image->resize($width,$height,Image::HEIGHT)->background("#fff");
           }
           $thumbImgPath = $this->getPath($targetFile);
           $thumbImgName = $this->getName($targetFile) . "_".$width."x".$height;
           $thumbImgExt = $this->getExt($targetFile);
           $image->save($thumbImgPath.DIRECTORY_SEPARATOR.$thumbImgName.$thumbImgExt);
       }



       /**
        * 重命名文件
        * @param $pathFormat
        * @return string
        */
       private function getFullName($pathFormat)
       {
           //替换日期事件
           $t = time();
           $d = explode('-', date("Y-y-m-d-H-i-s"));
           $format = $pathFormat;
           $format = str_replace("{yyyy}", $d[0], $format);
           $format = str_replace("{yy}", $d[1], $format);
           $format = str_replace("{mm}", $d[2], $format);
           $format = str_replace("{dd}", $d[3], $format);
           $format = str_replace("{hh}", $d[4], $format);
           $format = str_replace("{ii}", $d[5], $format);
           $format = str_replace("{ss}", $d[6], $format);
           $format = str_replace("{time}", $t, $format);

           //过滤文件名的非法自负,并替换文件名
           $oriName = $this->oriName;
           $oriName = preg_replace("/[\|\?\"\<\>\/\*\\\\]+/", '', $oriName);
           $format = str_replace("{filename}", $oriName, $format);

           //替换随机字符串
           $randNum = mt_rand(1, 1000000000) . mt_rand(1, 1000000000);
           if (preg_match("/\{rand\:([\d]*)\}/i", $format, $matches)) {
               $format = preg_replace("/\{rand\:[\d]*\}/i", substr($randNum, 0, $matches[1]), $format);
           }
           return $format;
       }

       /**
        * 创建目录
        * @param $fileName
        * @return bool
        */
       private function createDir($fileName) {
           $dirs = $this->getPath($fileName);
           if (!file_exists($dirs) && !mkdir($dirs,0777,true)) {
               return false;
           } elseif (!is_writable($dirs)) {
               return false;
           }
           return true;
       }

       /**
        * 获取目录名
        */
       private function getPath($fullPathAndFileName) {
           return substr($fullPathAndFileName,0,strpos($fullPathAndFileName,strrchr($fullPathAndFileName,'/')));
       }

       /**
        * 获取文件名
        */
       private function getName($fullPathAndFileName) {
           $full_name = substr($fullPathAndFileName,strrpos($fullPathAndFileName,"/")+1);
           return substr($full_name,0,strrpos($full_name,'.'));
       }

       private function getExt($fullPathAndFileName) {
           return substr($fullPathAndFileName,strrpos($fullPathAndFileName,"."));
       }
   }